//互斥
//抢票操作
#include <iostream>
#include "Thread.hpp"
#include <vector>
#include <string>
using namespace ThreadModule;

int g_tickets = 10000;

const int num = 4;

void route(int &tickets)
{
    while (true)
    {
        if (g_tickets > 0)
        {
            std::cout << "get tickets: " << g_tickets << std::endl;
            usleep(1000);
            g_tickets--;
        }   
        else
        {
            break;
        }
    }
}

int main()
{
    std::vector<Thread<int>> threads;
    //1. 创建一批线程
    for (int i = 0; i < num; i++)
    {
        std::string name = "thread-" + std::to_string(i + 1);
        threads.emplace_back(route, g_tickets, name);
    }

    //2. 启动一批线程
    for (auto &t : threads)
    {
        t.Start();
    }
    //3. 等待一批线程
    for (auto &t : threads)
    {
        t.Join();
        std::cout << "wait done, thread name: "  << t.name() << std::endl; 
    }
    return 0;
}




// //封装Thread测试
// #include <iostream>
// #include "Thread.hpp"
// #include <vector>
// #include <string>
// using namespace ThreadModule;

// void Print(int& cnt)
// {
//     while (cnt)
//     {
//         std::cout << "I am myself thread, cnt:" << cnt-- << std::endl;
//         sleep(1);
//     }
// }

// const int num = 10;
// int main()
// {
//     std::vector<Thread<int>> threads;
//     //1. 创建一批线程
//     for (int i = 0; i < num; i++)
//     {
//         std::string name = "thread-" + std::to_string(i + 1);
//         threads.emplace_back(Print, 10, name);
//     }

//     //2. 启动一批线程
//     for (auto &t : threads)
//     {
//         t.Start();
//     }
//     //3. 等待一批线程
//     for (auto &t : threads)
//     {
//         t.Join();
//         std::cout << "wait done, thread name: "  << t.name() << std::endl; 
//     }

//     // Thread<int> t1(Print, 10);
//     // std::cout << "name: " << t1.name() <<std::endl;
//     // t1.Start();

//     // t1.Join();
//     return 0;
// }









// #include <iostream>
// #include <pthread.h>
// #include <string>
// #include <unistd.h>
// #include <errno.h>
// #include <cstring>
// #include <cstdlib>

// //线程是可以分离的：默认的线程时join able
// //如果我们main thread不关系新线程的执行信息，我们可以将线程设置成分离状态——pthread_detach(tid)
// //理解分离：底层依旧属于同一个进程。只是不需要等待了。
// //一般都希望main thread是最后一个退出的，无论是否是join，detach
// std::string ToHex(pthread_t tid)
// {
//     char id[64];
//     snprintf(id, sizeof(id), "0x%lx", tid);
//     return id;
// }

// // int g_val = 100;
// __thread int g_val = 100;//__thread修饰 让全局变量私有，存放在线程局部存储


// void *threadfunc1(void *args)
// {
//     std::string name = static_cast<const char*>(args);

//     while (true)
//     {
//         sleep(1);
//         printf("%s, g_val: %d, &g_val: %p\n", name.c_str(), g_val, &g_val);//
//     }
//     // // pthread_detach(pthread_self());//自己设置成分离状态
//     // int cnt = 5;
//     // while (true)
//     // {
//     //     if (!(cnt--)) break;
//     //     std::cout << "I am a new thread : cnt : " <<  getpid() << cnt << " &cnt : " << &cnt << std::endl;//有自己的独立栈结构,cnt局部变量放在栈区
//     //     sleep(1);
//     // }

//     return nullptr;
// }

// void *threadfunc2(void *args)
// {
//     std::string name = static_cast<const char*>(args);

//     while (true)
//     {
//         printf("%s, g_val: %d, &g_val: %p\n", name.c_str(), g_val, &g_val);
//         g_val--;
//         sleep(1);
//     }
//     // // pthread_detach(pthread_self());//自己设置成分离状态
//     // int cnt = 5;
//     // while (true)
//     // {
//     //     if (!(cnt--)) break;
//     //     std::cout << "I am a new thread : cnt : " <<  getpid() << cnt << " &cnt : " << &cnt << std::endl;//有自己的独立栈结构
//     //     sleep(1);
//     // }

//     return nullptr;
// }

// int main()
// {
//     //有自己的独立栈结构
//     pthread_t tid1;
//     pthread_t tid2;

//     pthread_create(&tid1, nullptr, threadfunc1, (void*)"thread 1");
//     pthread_create(&tid2, nullptr, threadfunc2, (void*)"thread 2");

//     pthread_join(tid1, nullptr);
//     pthread_join(tid2, nullptr);



//     // pthread_detach(tid);//也可以由主线程设置成分离状态
//     // std::cout << "new tid : " << tid << ", hex tid : " << ToHex(tid) << std::endl;
//     // std::cout << "main tid : " << pthread_self() << ", hex tid : " << ToHex(pthread_self()) << std::endl;

//     // int cnt = 5;
//     // while (true)
//     // {
//     //     if (!(cnt--)) break;
//     //     std::cout << "I am a main thread ...." << getpid() << std::endl;
//     //     sleep(1);
//     // }

//     // std::cout << "main thread wait block" << std::endl;
//     // int n = pthread_join(tid, nullptr);
//     // std::cout << "main thread return : " << n << " : " << strerror(n) << std::endl;

//     return 0;
// }




















// #include <unistd.h>
// #include <thread>

// void threadrun(int num)
// {
//     while (num)
//     {
//         std::cout << "I am a new thread " << num-- << std::endl;
//         sleep(1);
//     }
// }
// //C++11中的线程
// int main()
// {
//     std::thread t1(threadrun, 10);
//     while (true)
//     {
//         std::cout << "I am a main thread " << std::endl;
//         sleep(1);
//     }
//     t1.join();
//     return 0;
// }